package cn.znzz.cjm.service.impl;

import cn.znzz.cjm.config.CourseRedis;
import cn.znzz.cjm.doc.QueryDoc;
import cn.znzz.cjm.domain.CourseType;
import cn.znzz.cjm.feign.CourseDocFeignClient;
import cn.znzz.cjm.mapper.CourseTypeMapper;
import cn.znzz.cjm.service.ICourseTypeService;
import cn.znzz.cjm.util.AjaxResult;
import cn.znzz.cjm.vo.CourseTypeVo;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/*
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author chenjiangmin
 * @since 2021-12-20
 */

@Service
public class CourseTypeServiceImpl_redis extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private CourseTypeMapper typeMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    private ReentrantLock lock=new ReentrantLock();
    @Autowired
    private CourseDocFeignClient docFeignClient;
    @Override
    public AjaxResult treeData() {
        // List<CourseType>  courseTypes = courseTypeMapper.treeData();
        List<CourseType> courseTypes = new ArrayList<>();
        Object obj = redisTemplate.opsForValue().get(CourseRedis.COURSE_REDIS_COMMON);
        if (obj != null){
            courseTypes = (List<CourseType>)obj;
            System.out.println("缓存");
        }else {
            if (lock.tryLock()){
                try {
                    int i = ThreadLocalRandom.current().nextInt(100, 200);
                    System.out.println("数据库");
                    courseTypes = typeData();
                    redisTemplate.opsForValue().set(CourseRedis.COURSE_REDIS_COMMON,courseTypes,Long.valueOf(i),TimeUnit.MINUTES);
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }else {
                try {
                    Thread.sleep(10L);
                    treeData();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
        return AjaxResult.me().setResultObj(courseTypes);
//        List<CourseType> courseTypes= grtTreeData();
//        return AjaxResult.me().setResultObj(courseTypes);
    }

    @Override
    public AjaxResult crumbs(Long typeid) {
        //返回给前端的值
        List<CourseTypeVo> result = new ArrayList<>();
        //获取id获取自己
        CourseType courseType = typeMapper.selectById(typeid);
        //获取path
        String path = courseType.getPath();
        //通过.来进行分割
        String[] ids = path.split("\\.");

        //遍历ids查询出对应的课程类型
        for(String id:ids){
            //将string的id转换为Long类型
            Long Lid = Long.valueOf(id);
            //查询出自己
            CourseType own = typeMapper.selectById(Lid);
            //查询出兄弟不包括自己
            EntityWrapper<CourseType> wrapper = new EntityWrapper<>();
            wrapper.eq("pid",own.getPid()).and().ne("id",own.getId());
            List<CourseType> bros = typeMapper.selectList(wrapper);
            //创建一个Vo把自己和兄弟姐妹装进去
            CourseTypeVo courseTypeVo = new CourseTypeVo(own,bros);
            result.add(courseTypeVo);

        }
        return AjaxResult.me().setResultObj(result);
    }

    @Override
    public boolean deleteById(Serializable id) {
        //删除redis
        Boolean delete = redisTemplate.delete(CourseRedis.COURSE_REDIS_COMMON);
        boolean b = super.deleteById(id);
        //如果删除未成功
        if(!delete){
            //睡眠，等待占用线程
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //再次删除
            redisTemplate.delete(CourseRedis.COURSE_REDIS_COMMON);
        }
        return b;
    }

    @Override
    public boolean updateById(CourseType entity) {
        //删除redis
        Boolean delete = redisTemplate.delete(CourseRedis.COURSE_REDIS_COMMON);
        boolean b = super.updateById(entity);
        //如果删除未成功
        if(!delete){
            //睡眠，等待占用线程
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //再次删除
            redisTemplate.delete(CourseRedis.COURSE_REDIS_COMMON);
        }
        return b;
    }

    @Override
    public boolean insert(CourseType entity) {
        //删除redis
        redisTemplate.delete(CourseRedis.COURSE_REDIS_COMMON);
        return super.insert(entity);
    }

    private List<CourseType> typeData() {
        List<CourseType> courseTypes = new ArrayList<>();
        //获取到所有的对象
        List<CourseType> typeList = typeMapper.selectList(null);
        //设置每一个id和对应对象的关系
        HashMap<Long, CourseType> map = new HashMap<>();
        //遍历出查询出来的集合
        for(CourseType type:typeList){
            map.put(type.getId(),type);
        }

        for(CourseType type:typeList){
            //查找出第一层级
            if(type.getPid() == 0){

                courseTypes.add(type);
            }else {//其他层级
                Long pid = type.getPid();
                CourseType parent = map.get(pid);
                parent.getChildren().add(type);
            }
        }
        return courseTypes;
    }
}
